import json

import time

from django.core.paginator import Paginator
from django.db import transaction
from django.http import HttpResponseForbidden
from django.http import JsonResponse
from django.shortcuts import render, redirect
from decimal import Decimal
from django.contrib.auth.mixins import LoginRequiredMixin

# Create your views here.
from django.utils import timezone
from django.views import View
from django_redis import get_redis_connection

from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from user.models import Address, User


class OrderSettlementView(LoginRequiredMixin, View):
    def get(self, request):
        # 1.接收数据
        user = request.user
        # 2.检验数据
        pass
        # 3.处理业务
        addresses = Address.objects.filter(user_id=user.id, is_deleted=False)

        redis_conn = get_redis_connection('carts')
        redis_cart = redis_conn.hgetall('cart_%s' % user.id)
        cart_selected = redis_conn.smembers('selected_%s' % user.id)
        total_count = 0  # 总数
        total_amount = 0  # 总价
        freight = 10  # 运费
        payment_amount = 0  # 总费用
        sku_list = []
        for sku_id in cart_selected:
            sku = SKU.objects.get(id=sku_id)
            sku_data = {
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image_url.url,
                'price': sku.price,
                'count': int(redis_cart[sku_id]),
                'amount': sku.price * int(redis_cart[sku_id]),
            }
            sku_list.append(sku_data)
            total_count += sku_data['count']
            total_amount += sku_data['amount']
            payment_amount = total_amount + freight
        context = {
            'addresses': addresses,
            'default_address_id': user.default_address_id,
            'skus': sku_list,
            'total_count': total_count,
            'total_amount': total_amount,
            'freight': freight,
            'payment_amount': payment_amount
        }
        # 4.返回响应
        return render(request, 'place_order.html', context=context)


class OrderCommitView(LoginRequiredMixin, View):
    def post(self, request):
        # 1.接收数据
        data = json.loads(request.body.decode())
        address_id = data['address_id']
        pay_method = data['pay_method']
        # 2.检验数据
        try:
            Address.objects.get(id=address_id)
        except Exception as e:
            return JsonResponse({'code': 9999, 'errmsg': '地址id有误'})
        if not pay_method in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
            return JsonResponse({'code': 9999, 'errmsg': '支付方式不正确'})
        user = request.user
        redis_conn = get_redis_connection('carts')
        cart_redis = redis_conn.hgetall('cart_%s' % user.id)
        cart_selected = redis_conn.smembers('selected_%s' % user.id)
        if len(cart_selected) < 1:
            return JsonResponse({'code': 9999, 'errmsg': '请选择商品'})

        for sku_id in cart_selected:
            if sku_id not in cart_redis:
                return JsonResponse({'code': 9999, 'errmsg': '商品数量有误'})
        # 3.处理业务
        # 保存订单
        order_id = "%s%09d" % (timezone.localtime().strftime('%Y%m%d%H%M%S'), user.id)

        total_count = 0
        total_amount = 0
        freight = 10
        if int(pay_method) == OrderInfo.PAY_METHODS_ENUM['ALIPAY']:
            status = OrderInfo.ORDER_STATUS_ENUM['UNPAID']
        else:
            status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']

        """
        sku = models.ForeignKey(SKU, on_delete=models.PROTECT, verbose_name="订单商品")
        count = models.IntegerField(default=1, verbose_name="数量")
        price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="单价")
        order = models.ForeignKey(OrderInfo, related_name='skus', on_delete=models.CASCADE, verbose_name="订单")
        """
        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                # 创建订单模型
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address_id=address_id,
                    total_count=total_count,
                    total_amount=total_amount,
                    freight=freight,
                    pay_method=pay_method,
                    status=status,
                )
                # 保存订单商品
                for sku_id in cart_selected:
                    while True:
                        sku = SKU.objects.get(id=sku_id)
                        count = int(cart_redis[sku_id])
                        price = sku.price

                        old_stock = sku.stock
                        old_sales = sku.sales
                        # 判断库存
                        if count > sku.stock:
                            transaction.savepoint_rollback(save_point)
                            return JsonResponse({'code': 9999, 'errmsg': '库存不足'})
                        # 模拟系统繁忙
                        # time.sleep(5)
                        # 减少库存,增加销量
                        new_stock = old_stock - count
                        new_sales = old_sales + count
                        # 更新数据库
                        res = SKU.objects.filter(id=sku_id, stock=old_stock, sales=old_sales).update(stock=new_stock,
                                                                                                     sales=new_sales)
                        print(res)
                        if res == 0:
                            # 没有更新成功
                            # transaction.savepoint_rollback(save_point)
                            # return JsonResponse({'code': 9999, 'errmsg': '系统繁忙'})
                            continue

                        break
                    # 订单信息累加
                    order.total_amount += count * price
                    order.total_count += count

                    OrderGoods.objects.create(
                        sku=sku,
                        count=count,
                        price=price,
                        order=order,
                    )
                order.save()

            except Exception as e:
                print(e)
                transaction.savepoint_rollback(save_point)
                return JsonResponse({'code': 9999, 'errmsg': '下单失败'})
        # 清楚购物车商品
        redis_conn.hdel('cart_%s' % user.id, *cart_selected)
        redis_conn.srem('selected_%s' % user.id, *cart_selected)

        # 4.返回响应
        res = {
            'code': 0,
            'errmsg': '成功',
            'order_id': order.order_id
        }
        return JsonResponse(res)


class OrderSuccessView(View):
    def get(self, request):
        # 1.接收数据
        data = request.GET
        order_id = data.get('order_id')
        payment_amount = data.get('payment_amount')
        pay_method = data.get('pay_method')
        username = request.user.username
        # 2.检验数据
        if not all([order_id, payment_amount, pay_method]):
            return JsonResponse({'code': 9999, 'errmsg': '参数不全'})
        try:
            order = OrderInfo.objects.get(order_id=order_id)
        except Exception as e:
            print(e)
            return JsonResponse({'code': 9999, 'errmsg': '订单不存在'})

        # 3.处理业务

        # 4.返回响应
        context = locals()
        return render(request, 'order_success.html', context=context)


class OrderInfoView(LoginRequiredMixin, View):
    def get(self, request, page_num):
        # 1.接收数据
        user = request.user
        orders = user.orderinfo_set.all()
        order_list = []
        # 2.检验数据
        per_page = 3
        p = Paginator(orders, per_page)
        current_page = p.page(page_num)
        current_order_all = current_page.object_list
        # 3.处理业务
        for order in current_order_all:
            order_data = {
                'order_id': order.order_id,
                'create_time': order.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                'total_count': order.total_count,
                'total_amount': order.total_amount,
                'freight': order.freight,
                'pay_method': order.pay_method,
                'status': order.status,
                'sku_list': []
            }
            sku_all = order.skus.all()
            for good in sku_all:
                sku_data = {
                    'default_image_url': good.sku.default_image_url.url,
                    'name': good.sku.name,
                    'price': good.price,
                    'count': good.count,
                    'amount': good.count * good.price
                }
                if not good.is_commented:
                    order_data['comment_status'] = '待评价'
                order_data["sku_list"].append(sku_data)
            order_list.append(order_data)

        # 4.返回响应
        context = {
            'orders': order_list,
            'current_page': page_num,
            'total_pages': p.num_pages
        }
        return render(request, 'user_center_order.html', context=context)


class OrderCommentView(LoginRequiredMixin, View):
    def get(self, request):
        # 1.接收数据
        data = request.GET
        order_id = data.get('order_id')
        # 2.检验数据
        try:
            order = OrderInfo.objects.get(order_id=order_id, status='4')
        except Exception as e:
            print(e)
            return HttpResponseForbidden('订单信息有误')
        # 3.处理业务
        goods_all = order.skus.all()
        goods_list = []
        for goods in goods_all:
            goods_data = {
                'order_id':goods.order_id,
                'sku_id':goods.sku_id,
                'image': goods.sku.default_image_url.url,
                'price': float(goods.price),
                'name': goods.sku.name
            }
            goods_list.append(goods_data)
        context = {
            'skus': goods_list
        }
        # 4.返回响应
        return render(request, 'goods_judge.html', context=context)
    def post(self,request):
        # 1.接收数据
        data = json.loads(request.body.decode())
        order_id = data['order_id']
        sku_id = data['sku_id']
        comment = data['comment']
        score = data['score']
        is_anonymous = True if data['is_anonymous'] == 'on' else False
        # 2.检验数据
        if not all([order_id,sku_id,comment,score]):
            return JsonResponse({'code':9999,'errmsg':'参数不全'})
        try:
            order = OrderInfo.objects.get(order_id=order_id, status='4')
        except Exception as e:
            print(e)
            return JsonResponse({'code':9999,'errmsg':'订单信息有误'})
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            print(e)
            return JsonResponse({'code':9999,'errmsg':'商品id有误'})
        try:
            goods = OrderGoods.objects.get(order=order, sku=sku)
        except Exception as e:
            return JsonResponse({'code':9999,'errmsg':'订单商品信息有误'})
        # 3.处理业务
        goods.comment = comment
        goods.score = score
        goods.is_anonymous = is_anonymous
        goods.is_commented = True
        goods.save()

        # 4.返回响应
        res = {
            'code':0,
            'errmsg':'成功'
        }
        return JsonResponse(res)


class DetailsCommmentView(View):
    def get(self,request,sku_id):
        # 1.接收数据
        """
        order = models.ForeignKey(OrderInfo, related_name='skus', on_delete=models.CASCADE, verbose_name="订单")
    sku = models.ForeignKey(SKU, on_delete=models.PROTECT, verbose_name="订单商品")
    count = models.IntegerField(default=1, verbose_name="数量")
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="单价")
    comment = models.TextField(default="", verbose_name="评价信息")
    score = models.SmallIntegerField(choices=SCORE_CHOICES, default=5, verbose_name='满意度评分')
    is_anonymous = models.BooleanField(default=False, verbose_name='是否匿名评价')
    is_commented = models.BooleanField(default=False, verbose_name='是否评价了')
        """
        # 2.检验数据
        try :
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code':9999,'errmsg':'订单商品不存在'})
        goods_all = OrderGoods.objects.filter(sku=sku,is_commented=True)
        if not goods_all:
            res = {
                'code': 0,
                'errmsg': '无评价',
                'goods_comment_list': []
            }
            return JsonResponse(res)
        # 3.处理业务
        goods_comment_list=[]
        for goods in goods_all:
            username = goods.order.user.username
            if goods.is_anonymous:
                username = username[0:1]+'***'+username[-1:]
            goods_data = {
                'comment': goods.comment,
                'score': goods.score,
                'username': username,
                'is_anonymous':goods.is_anonymous
            }
            goods_comment_list.append(goods_data)

        # 4.返回响应

        res = {
            'code':0,
            'errmsg':'成功',
            'goods_comment_list':goods_comment_list
        }
        return JsonResponse(res)